﻿////寻找质数，还有更优解法
//
//#include<string.h>
//#include <stdlib.h>
////#include <stdio.h>
////
////int main()
////{
////	int one, n;
////	scanf_s("%d %d", &one, &n);
////	printf("1 ");
////	for (int i = 2; i <= n; i++)
////	{
////		int flag = 1;//表示他是素数
////		for (int j = 2; j < i; j++)
////		{
////			if (i % j == 0)
////			{
////				flag = 0;//表示他不是素数
////			}
////			
////		}
////		if (flag == 1)
////				printf("%d ", i);
////	}
////	printf("%d", n);
////	return 0;
////}
//
////哈希算法
//#include <stdio.h>
//
//int main() {
//	int n;
//	scanf("%d", &n);
//	int q[100];
//	for (int i = 0; i < n; i++)
//		scanf("%d", &q[i]);
//
//	int exist[20001] = { 0 };  // 存两数之和（题目数字≤10000）
//	for (int i = 0; i < n; i++) {
//		for (int j = i + 1; j < n; j++) {
//			int sum = q[i] + q[j];
//			exist[sum] = 1;
//		}
//	}
//
//	int count = 0;
//	for (int i = 0; i < n; i++) {
//		if (exist[q[i]]) count++;
//	}
//
//	printf("%d\n", count);
//	return 0;
//}
//
////求因数个数————————有待拓展
//
//int main()
//{
//	int n;
//	scanf_s("%d", &n);
//	int* q1 = (int*)malloc(n * sizeof(int));
//	for (int i = 0; i < n; i++)
//	{
//		scanf_s("%d", &q1[i]);
//	}
//	for (int i = 0; i < n; i++)
//	{
//		int num = q1[i];
//		int count = 0;
//		for (int j = 1; j * j <= num; j++)
//		{
//			if (num % j == 0)
//			{
//				if (j * j == num)
//				{
//					count++;
//				}
//				else
//				{
//					count += 2;
//				}
//			}
//		}
//		printf("%d %d\n", q1[i], count);
//
//	}
//
//
//	return 0;
//}
//
////————————————       突然发现不会读取和输出字符串scanf————————————————————————————————————————
////int main()
////{
////    char name[11];                     // 最多存储10个字符 + '\0'
////    scanf_s("%s", name, sizeof(name) - 1); // 正确的 scanf_s 用法
////    printf("%s\n", name);
////    return 0;
////}
//
//
//
//// ——————————————————————————  鲁棒的代码——————————————————-
////优化后代码的 “灵活性”
////            scanf(" %c", ...) 里的空格是 “魔法”—— 它会自动跳过所有空白符（空格、换行、制表符），
////              解释的再详细些：会跳过前导的空白字符啥的，然后会再行位自动添加‘\0’
////               "从上一个 scanf 停止的地方继续" 是 scanf 函数的设计特性
////                  清除缓存   while (getchar() != '\n');
//// 使用 fgets（推荐）
//char comet[7];
//char group[7];
//fgets(comet, sizeof(comet), stdin);
//fgets(group, sizeof(group), stdin);
//
//// 或者使用 scanf 的宽度限制
//char comet[100];  // 大缓冲区
//char group[100];
//scanf("%6s", comet);  // 仍然只读6个字符
//scanf("%6s", group);
//
//
//
//
////_——————————————————————————————P1308 [NOIP 2011 普及组] 统计单词数————————————————————————
//1.对fgets函数基本掌握以及顺带掌握了strcspn函数（基本是配套的）
//
//fgets(reference, sizeof(reference), stdin);
//
//goal[strcspn(goal, "\n")] = '\0';
//
//2.strlen记数不包括'\0'
//
//3.记数要检查边界like this （很高效） 					
//
//    if (reference[i + z] == '\0')              结尾 
//    if (i == 0 || reference[i - 1] == ' ')     开头和中间
//
//4.tolower函数，大小写转换可以用到	其头文件<ctype.h				if (tolower(goal[0]) == tolower(reference[i]))
//
//5.逻辑关系       if(flag == 1 && (reference[i + z] == '\0' || reference[i + z] == ' '))
//    (1)注意逻辑关系的括号
//	(2)太细节了，'0' 不是字符'0 ',注意空格
//	(3)如果flag为1（即单词匹配成功）并且（当前匹配的单词后面是字符串结束符或者是空格）那么我们就认为匹配成功。
//
//6.如何存储第一次的值呢？？？
//
//if (position == -1)
//{ // 只记录第一次的位置
//	position = i;
//}
//               
//7.	变量更新，避免重复运算，为何-1,因为后自增++		i = i + z - 1;
//


//_——————————————————————————————P1553 数字反转（升级版）——————————————————————————————

//1.新鲜的函数
strchr函数，
在字符串中查找字符第一次出现的位置，注意格式;记得要进行安全检查	char* p = strchr(ch, '/');	if (!p) return; // 安全检查


                char* p = strchr(s, 'o');
函数体：char *strchr(const char *str,  int ch);
	char s[] = "hello world";
	char* p = strchr(s, 'o');  // 查找 'o' 第一次出现的位置
	if (p != NULL)//检查是否为空指针
	
	fgets(ch, sizeof(ch), stdin);
	ch[strcspn(ch, "\n")] = '\0';
	if (strlen(ch) == 0) return 0;//检查安全性

	if (strchr(ch, '.'))
		decimal(ch);
	else if (strchr(ch, '/'))
		fraction(ch);
	else if (strchr(ch, '%'))
		percentage(ch);
	else
		integer(ch);

	函数2：  
		
		        strncpy函数(#include <string.h>)
		strncpy 用来 从字符串 src 复制最多 n 个字符到 dest。它常用于 安全地复制字符串，防止越界。
		char src[] = "Hello";
    	char dest[10];

	   strncpy(dest, src, 3);  // 只复制前3个字符
	   dest[3] = '\0';         // 手动加上结束符！

	   printf("dest = %s\n", dest);  // 输出：Hel




	 函数3：
		       strncpy_s函数
		 最安全用法： if (strncpy_s(dest, sizeof(dest), src, _TRUNCATE) != 0)没 关系，能放多少放多少，自动截断并加上 \0 结尾。”	 
	 {
		 // 出错处理
	 }
	 _TRUNCATE 仅在 _s 系列函数中有效，不能用在普通函数（如 strncpy、sprintf）
	 {
			 // 出错处理
		 }

		   char src[] = "Hello, World!";
		   char dest[10];

		   errno_t err = strncpy_s(dest, sizeof(dest), src, 5);
		   if (err == 0) 
		   {
			   printf("复制成功：%s\n", dest);
		   }
		   else 
		   {
			   printf("复制失败，错误码：%d\n", err);
		   }

2.算法优化部分：

（1）strchr函数，函数，查找单个字符，进入相对应函数
（2）数字转换部分（整数），需要注意的细节是：int l,r可以一次定义两个变量，但是不能分别定义两个变量

    无需判断奇偶：
	int len = strlen(ch);
    for (int l = 0, r = len - 1; l < r; l++, r--)
{
	char t = ch[l];
	ch[l] = ch[r];
	ch[r] = t;
}
 
（3）前导0的处理方式以及特殊情况考虑
while (ch[start] == '0' && ch[start +1] != '\0')//想象输入 "0"：第二个条件存在的意义
	{
		start++;
	}
	printf("%s", ch+start);


（4)	同元素指针相减表示元素间距，同一个数组
          不好：while (ch[j] != '.')j++;//计算整数部分有多少，整数部分应该是j位
           好 ： char* p = strchr(ch, '.'); // 找到小数点,同类型指针相减，表示元素间距
		         int int_len = p - ch;      // 整数部分长度

(5)小数部分前导为0的情况处理：
int end = i;（去\0后的总长度）
while (end > j && ch[end] == '0')   j是整数部分长度
                 end--;
        if (ch[end] == '.')
           end++; // 如果小数全是零，保留一个0

        ch[end + 1] = '\0';
      printf("%s\n", ch + start);